home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / Virtual User 1.0 / Example Scripts / TowersOfHanoi.vu < prev   
Text File  |  1991-01-25  |  8KB  |  246 lines

  1. #
  2. #    File:        TowersOfHanoi.vu
  3. #
  4. #    Contains:    The script solves the problem of Towers of Hanoi.
  5. #                To be able to run this script, the target should be in
  6. #                Finder, with either a window open or a volume selected.
  7. #
  8. #                To Run this script set the following variables towards the end
  9. #                of this file: (default values in parens)
  10. #                Total_disks(3) : the number of disks you want the towers to be
  11. #                                 built with.
  12. #                From_tower(1) : the tower from which you want to move;
  13. #                To_tower(3) : the tower to which you want to move;
  14. #                Using_tower(2): the tower which will be used as a temporary one
  15. #
  16. #    Prerequisite: This script makes use of the tasks library UtilityTasksLib.vu
  17. #                Make sure this library is put into the Libraries folder of your 
  18. #                Virtual User folder.
  19. #
  20. #    Warning:    This script will create a set of folders in the open/selected 
  21. #                volume. So do trash these folders after the script completes
  22. #                its execution. Also, if the folders with the names used already 
  23. #                exist (from previous execution) the script will not work.
  24. #                
  25. #                
  26. #    Written by:    P Nagarajan
  27. #
  28. #    Copyright:    © 1989 by Apple Computer, Inc., all rights reserved.
  29. #
  30. #    Change History:
  31. #
  32. #        3/29/89       naga         Creation
  33. #                             
  34. #
  35. #    To Do:
  36. #
  37.  
  38. Libraries "UtilityTasksLib.vu";
  39.  
  40.  
  41. task add_move(from_t, to_t, all_moves)
  42. #adds a move of the form {from_t, to_t} to the global list 'all_moves'.
  43. # all Arguments should be integers
  44. begin
  45.     all_moves := all_moves + {{from_t, to_t}};
  46.     return all_moves;
  47. end;
  48.  
  49. task gen_moves(from_t, to_t, using, num_disks, all_moves)
  50. #generates moves for moving 'num_disks' number of disks from 'from_t' tower
  51. #to 'to_t' tower using 'using' tower
  52. # all Arguments should be integers
  53. begin
  54.     if not (num_disks = 0) do
  55.     begin
  56.         if (num_disks = 1) do
  57.             return add_move(from_t, to_t, all_moves);
  58.         else do
  59.         begin
  60.             all_moves := gen_moves(from_t, using, to_t, num_disks - 1, all_moves);
  61.             all_moves := add_move(from_t, to_t, all_moves);
  62.             all_moves := gen_moves(using, to_t, from_t, num_disks - 1, all_moves);
  63.             return all_moves;
  64.         end;
  65.     end;
  66. end; #task gen_moves
  67.  
  68. task set_up_tower(tower, no_of_disks)
  69. #sets up the tower called Tower{tower} made of 'no_of_disks'
  70. #Prereqs::  'Base_dimension' : an integer specifying the size of the base disk(window)
  71. #            'Position_of_tower' : a list having the initial position of each tower,
  72. #                                  position being {x, y}.
  73. #Results:: 'Delta_for_tower' : sets up this global list, which gives the displacement of the topmost
  74. #                               disk from the base, on each tower. ( a list of 3 integers).
  75. #           'success' : if setup successful returns true else false.
  76. begin
  77.     global Screen_rect;
  78.     global Base_dimension;
  79.     global Position_of_tower;
  80.     j := tower; #tower number
  81.     i := no_of_disks;
  82.     if (OpenOneWindow()) do
  83.     begin
  84.         Drag [Window] a: {Screen_rect[3]-12, Screen_rect[4]-50};
  85.         Select [MenuItem t: 'New Folder' m:'File'];
  86.         Type k:{"Tower{j}"};
  87.         Select [MenuItem t:'Open' m:'File'];
  88.         Drag [Window t:"Tower{j}"] a: {1,20};
  89.         Size [Window t:"Tower{j}"] h: Base_dimension w:Base_dimension;
  90.         Drag [Window t:"Tower{j}"] a: {Screen_rect[3]-12, Screen_rect[4]-50};
  91.         global Delta_for_tower := {0,0,0};
  92.         delta_move := Delta_for_tower[j];
  93.         while (i > 0) do
  94.         begin
  95.             Select [Window t:"Tower{j}"];
  96.             Select [MenuItem t: 'New Folder' m:'File'];
  97.             Type k:{"Disk{i}"};
  98.             Select [MenuItem t:'Open' m:'File'];
  99.             new_position := {(Position_of_tower[j][1] + delta_move),
  100.                              (Position_of_tower[j][2] - delta_move) };
  101.             if not (match[window t: "Disk{i}"]!) 
  102.             begin
  103.                 println "couldn't find window: Disk{i}: ", i;
  104.                 exit;
  105.             end;
  106.             Drag [Window t:"Disk{i}"] a: {1,20};
  107.             Size [Window t:"Disk{i}"] h:Base_dimension - delta_move/2 w:Base_dimension - 2*delta_move;
  108.             Drag [Window t:"Disk{i}"] a: new_position;
  109.             delta_move := delta_move + 5;
  110.             i := i - 1;
  111.         end;
  112.         Delta_for_tower := replace((delta_move - 5), j, Delta_for_tower);
  113.         success := true;
  114.     end; #if one window opened successfully
  115.     else do
  116.     begin
  117.         success := false;
  118.     end; #could not open a single window
  119.     return success;
  120. end; #task set_up_tower
  121.  
  122. task make_moves(all_moves)
  123. #this task actually makes the moves (dragging windows) using the moves,
  124. #stored in the argument 'all_moves'.
  125. #Prereqs :: 'all_moves' a list containing moves of form {i,j}
  126. #            'Position_of_tower' : a list having the initial position of each tower,
  127. #                                  position being {x, y}.
  128. #            'Delta_for_tower' : a list which gives the displacement for the next disk 
  129. #                                to be placed on a tower (from the original position of the tower).
  130. begin
  131.     global Delta_for_tower;
  132.     global Position_of_tower;
  133.     x := 1; #index to get x-coord
  134.     y := 2; #index to get y-coord
  135.     for each disk_move in all_moves do 
  136.     begin 
  137.         i := disk_move[1] ;
  138.         j := disk_move[2] ; #move from tower i to tower j
  139.         delta_move := Delta_for_tower[j] + 5;
  140.         newx := Position_of_tower[j][x] + delta_move;
  141.         newy := Position_of_tower[j][y] - delta_move;
  142.         new_position := {newx, newy};
  143.         wind_rect := {Position_of_tower[i][x] + Delta_for_tower[i], #left
  144.                       Position_of_tower[i][y] - Delta_for_tower[i], #top
  145.                       0 ,#right
  146.                       0 #bottom
  147.                       };
  148.         Select [Window t:?selected_title r:wind_rect];
  149.         match [Window t:?drag_title o:1];
  150.         if selected_title <> drag_title 
  151.         begin
  152.             println "looking for window: ", selected_title;
  153.             println "found window: ", drag_title;
  154.             exit;
  155.         end;
  156.         Drag [Window t:drag_title o:1] a: new_position;
  157.         Delta_for_tower := update_Delta_for_tower(delta_move, i, j, Delta_for_tower);
  158.     end; #for_each move
  159. end; #task make_moves
  160.  
  161. task update_Delta_for_tower(delta_move, from_t, to_t, Delta_for_tower)
  162. begin
  163.     if (Delta_for_tower[from_t] <> 0) do
  164.         Delta_for_tower := replace((Delta_for_tower[from_t] - 5), from_t, Delta_for_tower);
  165.     Delta_for_tower := replace(delta_move, to_t, Delta_for_tower);
  166.     return Delta_for_tower;
  167. end; #task update_Delta_for_tower
  168.  
  169.  
  170. task find_screen_dimensions()
  171. begin
  172.     global Screen_rect, Screen_width, Screen_height;
  173.     match[screen r:?Screen_rect m:true];
  174.     Screen_width := Screen_rect[3]- Screen_rect[1];
  175.     Screen_height := Screen_rect[4]- Screen_rect[2];
  176. end; #find_screen_dimensions
  177.  
  178. task check_for_max_tower_size(total_disks)
  179. begin
  180.     global Screen_width, Screen_height;
  181.     max_disks1 := ((Screen_height - 20) - 112)/5;
  182.     max_disks2 := (((Screen_width - 30)/3) - 112)/5;
  183.     if max_disks2 >= max_disks1 #find the tighter of the two bounds
  184.     begin
  185.         max_tower_size := max_disks1;
  186.     end;#if
  187.     else
  188.     begin
  189.         max_tower_size := max_disks2;
  190.     end;#if
  191.     if total_disks > max_tower_size
  192.     begin
  193.         println "Sorry can draw only tower with a maximum of ", max_tower_size,
  194.               " disks on this target's main screen.";
  195.         println "Try with lesser number of disks or a larger screen!";
  196.         exit;
  197.     end;#if
  198.     return true;
  199. end; #check_for_max_tower_size
  200.  
  201. task set_tower_dimensions_and_position(total_disks)
  202. begin
  203.     global Base_dimension, Position_of_tower, Screen_rect, Screen_width, Screen_height;
  204.     Base_dimension := 117 + 5*(total_disks - 1);
  205.     x_offset := (Screen_width-Base_dimension*3)/4;
  206.     y_offset := (Screen_height-Base_dimension)/2;
  207.     Position_of_tower := {{(Screen_rect[1] + x_offset),(Screen_rect[2] + y_offset)},
  208.                           {(Screen_rect[1] + x_offset*2 + Base_dimension), (Screen_rect[2] + y_offset)},
  209.                           {(Screen_rect[1] + x_offset*3 + Base_dimension*2), (Screen_rect[2] + y_offset)}};
  210.  
  211. end;# set_tower_dimensions_and_position
  212.  
  213. All_moves := {};
  214. From_tower := 1;
  215. To_tower := 3;
  216. Using_tower := 2;
  217. Total_disks := 3;
  218.  
  219. System7 := RunningSystemSeven();;
  220. if (System7) # 7.0.x system software on target
  221. begin
  222.     Patience(6);
  223. end; #if System7
  224.  
  225. find_screen_dimensions();
  226.  
  227. if (check_for_max_tower_size(Total_disks))
  228. begin
  229.     set_tower_dimensions_and_position(Total_disks);
  230.     println "Now computing the moves...";
  231.     All_moves := gen_moves(From_tower, To_tower, Using_tower, Total_disks, All_moves);
  232.     println "done!";
  233.     println "Now setting up the tower of disks...";
  234.     success := set_up_tower(From_tower, Total_disks); 
  235.     if (success) do 
  236.     begin
  237.         println "done!";
  238.         println "Now making the moves...";
  239.         make_moves(All_moves);
  240.         println "done!";
  241.     end;
  242.     else do
  243.         println "Target not set up to solve the problem. Sorry.";
  244. end;#if Total_disks permissible
  245.  
  246.